package graph;

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.List;
import java.util.Vector;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import model.Collection;

public class GraphGenerator {

	/**
	 * 
	 * @param topicScoreFile
	 *            The file that keeps original topicality scores
	 * @param outputFile
	 *            The graph file
	 * @param T
	 *            The threshold, the scope of the decay function
	 */
	public static void createFlowGraph(String topicScoreFile,
			String outputFile, int T) {
		Vector<Double> topicScores = new Vector<Double>();
		try {
			BufferedReader reader = new BufferedReader(new FileReader(
					topicScoreFile));
			String line = null;
			while ((line = reader.readLine()) != null) {
				double score = Double.parseDouble(line.substring(line
						.indexOf(' ')));
				topicScores.add(score);
			}
			reader.close();
			double min = topicScores.get(0);
			double max = topicScores.get(0);

			for (int i = 0; i < topicScores.size(); i++) {
				if (topicScores.get(i) < min) {
					min = topicScores.get(i);
				}

				if (max < topicScores.get(i)) {
					max = topicScores.get(i);
				}
			}

			for (int i = 0; i < topicScores.size(); i++) {
				double value = topicScores.get(i);
				value = (value - min) / (max - min);
				topicScores.set(i, value);
			}

			PrintWriter writer;
			try {
				writer = new PrintWriter(outputFile);

				for (int i = 0; i < topicScores.size(); i++) {
					writer.write('s' + " " + i + " " + (1 - topicScores.get(i))
							+ '\n');
					writer.write(i + " " + 't' + " " + topicScores.get(i)
							+ '\n');
					// for (int j = 0; j < topicScores.size(); j++) {
					// double assocCost = getAssociationCost(i, j);
					// if (assocCost != 0 && i != j) {
					// writer.write(i + " " + j + " " + assocCost +'\n');
					// }
					// }
				}

				// System.out.println("Writing to " + location + sep + id +
				// ".lgl");
				writer.close();
			} catch (FileNotFoundException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}

	public static void createGraph(String topicScoreFile,
			String sentimentScoreFile, String outputFile, double T) {
		Vector<Double> topicScores = new Vector<Double>();
		Vector<Double> sentimentScores = new Vector<Double>();
		try {
			BufferedReader reader = new BufferedReader(new FileReader(
					topicScoreFile));
			String line = null;
			while ((line = reader.readLine()) != null) {
				double score = Double.parseDouble(line.substring(line
						.indexOf(' ')));
				topicScores.add(score);
//				System.out.println("topic: " +score);
			}
			reader.close();
			reader = new BufferedReader(new FileReader(sentimentScoreFile));
			while ((line = reader.readLine()) != null) {
				double score = Double.parseDouble(line.substring(line
						.indexOf(' ')));
				sentimentScores.add(score);
//				System.out.println("sentiment: " +score);
			}
			reader.close();
			PrintWriter writer = new PrintWriter(outputFile);
			int count = 0;
			for (int i = 0; i < topicScores.size(); i++) {
				for (int j = i; j < topicScores.size(); j++) {
					if (i != j) {
						double weight = getWeight(i, j, topicScores,
								sentimentScores);
						if (weight > T) {
							writer.write(i + " " + j + " " + weight + "\n");
							count++;
						}
					}
				}
			}
			System.out.println("Number of edges: " + count);
			writer.close();
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	public static void processDirectory(String rootDir, double threshold) {
		List<String> sentimentFiles = Collection.addDirectory(rootDir
				+ Collection.getSeparator() + "sentiment", false);
		List<String> topicFiles = Collection.addDirectory(
				rootDir + Collection.getSeparator() + "topic", false);
		for (int i = 0; i < sentimentFiles.size(); i++) {
			String outFile = topicFiles.get(i);
			outFile = rootDir.concat(Collection.getSeparator() + "graph"
					+ Collection.getSeparator() + extractBlogID(outFile)
					+ ".sum");
			System.out.println(outFile);
			 createGraph(topicFiles.get(i), sentimentFiles.get(i), outFile,
			 threshold);
			//createFlowGraph(topicFiles.get(i), outFile, 4);
		}
	}

	private static String extractBlogID(String path) {
		// BLOG06-20060221-000-0017941619__4-output.txt.main
		Pattern pattern = Pattern.compile("BLOG\\d+-\\d+-\\d+-\\d+__\\d");
		Matcher matcher = pattern.matcher(path);
		if (matcher.find()) {
			return path.substring(matcher.start(), matcher.end());
		}
		return null;
	}

	private static double getWeight(int i, int j, Vector<Double> topicScores,
			Vector<Double> sentimentScores) {
		double iScore = topicScores.get(i) * sentimentScores.get(i);
		double jScore = topicScores.get(j) * sentimentScores.get(j);
		double assoc = getAssociationCost(i, j);
		// System.out.println(i + ">" + j + " " + String.format("%.4f", assoc) +
		// " " + String.format("%.4f", iScore) + " " +
		// String.format("%.4f", jScore));
		return assoc * (iScore + jScore);
	}

	private static double getAssociationCost(int i, int j) {
		int distance = Math.abs(i - j);
		return (distance <= 4 ? Math.pow(Math.E, 1 - distance) : 0);
	}

	public static void main(String args[]) {
		processDirectory("C:\\Users\\Amos\\workspace\\Data\\selected\\933\\res", 0);
//		createGraph("C:\\Users\\Amos\\workspace\\Data\\selected\\875\\res\\sentiment\\BLOG06-20051209-098-0017741383__4-output.txt.main.score",
//				"C:\\Users\\Amos\\workspace\\Data\\selected\\875\\res\\topic\\BLOG06-20051209-098-0017741383__4-output.txt.main.score", "BLOG06-20051209-098-0017741383__4", 0); 
	}
}
